﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static ConsoleApp1.Program;

namespace ConsoleApp1
{
    internal class Program
    {
        //桥接模式：将抽象与现实分离，使两者可以各自单独变化而不受对方约束，使用时再将他们组合起来，如此降低了抽象与现实的耦合度，以此保证系统的可扩展性。
        //桥接模式就是为了解决这种“多维度变化”带来的“类爆炸”问题而生的。

        //这里的Shape为抽象类，ShapeColor也为抽象类
        static void Main(string[] args)
        {
            //根据不同分工的类进行任意的组合桥接，实现了所有类型的笛卡尔积
            Red red1 = new Red(new Circle());
            Red red2=new Red(new Rectangle());
            Red red3 = new Red(new Triangle());
            red1.DrawShapeColored();   
            red2.DrawShapeColored();   
            red3.DrawShapeColored();   

            Green green1 = new Green(new Circle());
            Green green2 = new Green(new Rectangle());
            Green green3 = new Green(new Triangle());
            green1.DrawShapeColored();
            green2.DrawShapeColored();
            green3.DrawShapeColored();
            
            Black black1 = new Black(new Circle());
            Black black2 = new Black(new Rectangle());
            Black black3 = new Black(new Triangle());

            black1.DrawShapeColored();
            black2.DrawShapeColored();
            black3.DrawShapeColored();
        }

        #region 将颜色和形状分开，允许客户端根据自己的需求进行任意的组合
        #region 形状
        public abstract class Shape
        {
            public abstract void DrawShape();
        }
 
        public class Triangle : Shape
        {
            public override void DrawShape()
            {
                Console.WriteLine("绘制三角形");
            }
        }
        public class Rectangle:Shape
        {
            public override void DrawShape()
            {
                Console.WriteLine("绘制矩形");
            }
        }
        public class Circle:Shape
        {
            public override void DrawShape()
            {
                Console.WriteLine("绘制圆形");
            }
        }
        #endregion

        #region 颜色
        public abstract class ShapeColor
        {
            protected Shape Shape;
            public ShapeColor(Shape shape)
            {
                this.Shape = shape;
            }

            public abstract void DrawShapeColored();

        }

        public class Black : ShapeColor
        {
            public Black(Shape shape) : base(shape)
            {

            }

            public override void DrawShapeColored()
            {
                Console.Write("使用黑色");
                this.Shape.DrawShape();
            }
        }

        public class Red : ShapeColor
        {
            public Red(Shape shape) : base(shape)
            {
            }

            public override void DrawShapeColored()
            {
                Console.Write("使用红色");
                this.Shape.DrawShape();
            }
        }

        public class Green : ShapeColor
        {
            public Green(Shape shape) : base(shape)
            {
            }

            public override void DrawShapeColored()
            {
                Console.Write("使用绿色");
                this.Shape.DrawShape();
            }
        }

        #endregion
        #endregion

        #region 将GUI空间与系统绘图API分开
        /// <summary>
        /// GUI绘图接口（抽象）
        /// </summary>
        public interface IGUI
        {
            void Draw();
        }

        /// <summary>
        /// 系统绘图渲染接口（现实）
        /// </summary>
        public interface IImp
        {
            /// <summary>
            /// 画线
            /// </summary>
            void DrawLine();

            /// <summary>
            /// 画矩形
            /// </summary>
            void DrawRect();

            /// <summary>
            /// 画圆
            /// </summary>
            void DrawCircle();
        }

        #region IGUI实现
        public class Window : IGUI
        {
            IImp imp;
            public Window(IImp imp)
            {
                this.imp = imp;
            }
            public void Draw()
            {
                this.imp.DrawRect();
                this.imp.DrawCircle();
                this.imp.DrawLine();
                this.imp.DrawLine();
            }
        }

        public class UserControl : IGUI
        {
            IImp imp;
            public UserControl(IImp imp)
            {
                this.imp = imp;
            }
            public void Draw()
            {
                this.imp.DrawRect();
                this.imp.DrawCircle();
            }
        }
        #endregion

        #region IWindow实现
        public class WindowXP : IImp
        {
            public void DrawCircle()
            {
                throw new NotImplementedException();
            }

            public void DrawLine()
            {
                throw new NotImplementedException();
            }

            public void DrawRect()
            {
                throw new NotImplementedException();
            }
        }

        public class Mac : IImp
        {
            public void DrawCircle()
            {
                throw new NotImplementedException();
            }

            public void DrawLine()
            {
                throw new NotImplementedException();
            }

            public void DrawRect()
            {
                throw new NotImplementedException();
            }
        }

        public class Linux : IImp
        {
            public void DrawCircle()
            {
                throw new NotImplementedException();
            }

            public void DrawLine()
            {
                throw new NotImplementedException();
            }

            public void DrawRect()
            {
                throw new NotImplementedException();
            }
        }
        #endregion

        #region 遥控器与设备
        /// <summary>
        /// 遥控器（抽象）
        /// </summary>
        public interface IRemoteController
        {
            void TurnOn();
            void TurnOff();
        }

        /// <summary>
        /// 设备（现实）
        /// </summary>
        public interface IDevice
        {
            void TurnOn();
            void TurnOff();
            void SetVolumn(double value);
        }

        #region IRemoteController
        public class GameRemoteController : IRemoteController
        {
            IDevice device;
            public GameRemoteController(IDevice device)
            {
                this.device = device;
            }

            public void TurnOff()
            {
                this.device.TurnOff();
            }

            public void TurnOn()
            {
                this.device.TurnOn();
            }
        }

        public class TVRemoteController : IRemoteController
        {
            IDevice device;
            public TVRemoteController(IDevice device)
            {
                this.device = device;
            }

            public void TurnOff()
            {
                this.device.TurnOff();
            }

            public void TurnOn()
            {
                this.device.TurnOn();
            }
        }

        #endregion

        #region Device
        /// <summary>
        /// 电视
        /// </summary>
        public class TV : IDevice
        {
            public void SetVolumn(double value)
            {
                throw new NotImplementedException();
            }

            public void TurnOff()
            {
                throw new NotImplementedException();
            }

            public void TurnOn()
            {
                throw new NotImplementedException();
            }
        }

        /// <summary>
        /// 收音机
        /// </summary>
        public class Radio : IDevice
        {
            public void SetVolumn(double value)
            {
                throw new NotImplementedException();
            }

            public void TurnOff()
            {
                throw new NotImplementedException();
            }

            public void TurnOn()
            {
                throw new NotImplementedException();
            }
        }

        /// <summary>
        /// 音响
        /// </summary>
        public class SoundSystem : IDevice
        {
            public void SetVolumn(double value)
            {
                throw new NotImplementedException();
            }

            public void TurnOff()
            {
                throw new NotImplementedException();
            }

            public void TurnOn()
            {
                throw new NotImplementedException();
            }
        }

        #endregion
        #endregion

        #region 支付与支付方式
        /// <summary>
        /// 支付（抽象）
        /// </summary>
        public interface IPay
        {
            void Authorize();
            void Pay();

        }

        /// <summary>
        /// 支付方式（现实）
        /// </summary>
        public interface IPayGate
        {
            bool SendAuthRequest();
            void SendPayRequest();
        }

        #region IPay
        /// <summary>
        /// 信用卡
        /// </summary>
        public class CreditCard : IPay
        {
            IPayGate paygate;
            public void SetPayWay(IPayGate paygate)
            {
                this.paygate = paygate;
            }
            public void Authorize()
            {
                this.paygate.SendAuthRequest();
                //特有操作... ...
            }

            public void Pay()
            {
                this.paygate.SendPayRequest();
                //特有操作... ...
            }
        }

        public class PayPal : IPay
        {
            IPayGate paygate;
            public void SetPayWay(IPayGate paygate)
            {
                this.paygate = paygate;
            }
            public void Authorize()
            {
                this.paygate.SendAuthRequest();
                //特有操作... ...
            }

            public void Pay()
            {
                this.paygate.SendPayRequest();
                //特有操作... ...
            }
        }

        public class Wallet : IPay
        {
            IPayGate paygate;
            public void SetPayWay(IPayGate paygate)
            {
                this.paygate = paygate;
            }
            public void Authorize()
            {
                this.paygate.SendAuthRequest();
            }

            public void Pay()
            {
                this.paygate.SendPayRequest();
            }
        }
        #endregion

        #region IPayGate
        public class StripeGateway : IPayGate
        {
            public bool SendAuthRequest()
            {
                throw new NotImplementedException();
            }

            public void SendPayRequest()
            {
                throw new NotImplementedException();
            }
        }

        public class PayPalGateWay: IPayGate
        {
            public bool SendAuthRequest()
            {
                throw new NotImplementedException();
            }

            public void SendPayRequest()
            {
                throw new NotImplementedException();
            }
        }

        public class BankDirectGateway : IPayGate
        {
            public bool SendAuthRequest()
            {
                throw new NotImplementedException();
            }

            public void SendPayRequest()
            {
                throw new NotImplementedException();
            }
        }
        #endregion
        #endregion
        #endregion
    }
}
